//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy
//===============================================================================

using System;
using System.Globalization;
using System.Text;

namespace EntLibContrib.Logging.Parser
{
	/// <summary>
	/// TimeStamp function parser
	/// </summary>
	public class TimeStampFunctionParser
	{
		#region Fields
		private string parsingTemplate;
		private ITimeStampParser theTimeStampParser;
		#endregion

		#region Properties
		/// <summary>
		/// Gets the parsing template.
		/// </summary>
		/// <value>The parsing template.</value>
		public string ParsingTemplate
		{
			get { return parsingTemplate; }
		}

		/// <summary>
		/// Gets the time stamp parser.
		/// </summary>
		/// <value>The time stamp parser.</value>
		public ITimeStampParser TimeStampParser
		{
			get { return theTimeStampParser; }
		}
		#endregion

		#region Construction
		/// <summary>
		/// Constructor to initialize a new instance of the class.
		/// </summary>
		/// <param name="template">The template.</param>
		/// <param name="formatProvider">The format provider.</param>
		public TimeStampFunctionParser(string template, IFormatProvider formatProvider)
		{
			StringBuilder templateBuilder = new StringBuilder(template);
			string functionArg = GetArgAndUpdateTemplate(templateBuilder);
			parsingTemplate = templateBuilder.ToString();
			if (functionArg == null)
			{
				if (formatProvider == null)
					theTimeStampParser = new TimeStampParser(CultureInfo.CurrentCulture);
				else
					theTimeStampParser = new TimeStampParser(formatProvider);
			}
			else
			{
				if (functionArg == TimeStampParserFraction.TimeStampFormat)
				{
					if (formatProvider == null)
						theTimeStampParser = new TimeStampParserFraction(CultureInfo.CurrentCulture);
					else
						theTimeStampParser = new TimeStampParserFraction(formatProvider);
				}
				else if (functionArg == TimeStampParserLocal.TimeStampFormat)
				{
					if (formatProvider == null)
						theTimeStampParser = new TimeStampParserLocal(CultureInfo.CurrentCulture);
					else
						theTimeStampParser = new TimeStampParserLocal(formatProvider);
				}
				else
				{
					if (formatProvider == null)
						theTimeStampParser = new TimeStampParserFormat(functionArg, CultureInfo.CurrentCulture);
					else
						theTimeStampParser = new TimeStampParserFormat(functionArg, formatProvider);
				}
			}
		}
		#endregion

		#region Private Methods
		private static string GetArgAndUpdateTemplate(StringBuilder messageBuilder)
		{
			const string startDelimiter = "{timeStamp(";
			const string endDelimiter = ")}";
			int startPos = 0;
			while (startPos < messageBuilder.Length)
			{
				string messageString = messageBuilder.ToString();
				if (messageString.IndexOf(startDelimiter, StringComparison.CurrentCulture) == -1)
				{
					break;
				}

				int tokenStartPos = messageString.IndexOf(startDelimiter, startPos, StringComparison.CurrentCulture) + startDelimiter.Length;
				int endPos = messageString.IndexOf(endDelimiter, tokenStartPos, StringComparison.CurrentCulture);
				string tokenTemplate = messageString.Substring(tokenStartPos, endPos - tokenStartPos);

				string tokenToReplace = startDelimiter + tokenTemplate + endDelimiter;
				startPos = messageBuilder.ToString().IndexOf(tokenToReplace, StringComparison.CurrentCulture);

				messageBuilder.Replace(tokenToReplace, "{timeStamp}");

				return tokenTemplate;
			}
			return null;
		}
		#endregion
	}
}
